#include "pwmled.h"
#include "rcc.h"


/** @defgroup PWMLED_Private_Functions
  * @{
  */

/**
  * @brief  Deinitializes the PWMLEDx peripheral registers to their default reset values.
  * @param  PWMLEDx: Select the PWMLED peripheral. 
  * @retval None
  */
void PWMLED_DeInit(PWMLED_TypeDef* PWMLEDx)
{
		if(PWMLEDx == PWMLED)
		{
			RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWMLED, ENABLE);
			RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWMLED, DISABLE);				
		}

}

/**
  * @brief  Initializes the PWMLEDx peripheral according to the specified
  *         parameters in the PWMLED_InitStructure .
  * @param  PWMLEDx: Select the PWMLED peripheral. 
  * @param  PWMLED_InitStructure: pointer to a PWMLED_InitTypeDef structure
  *         that contains the configuration information for the specified PWMLED 
  *         peripheral.
  * @retval None
  */
void PWMLED_Init(PWMLED_TypeDef* PWMLEDx, PWMLED_InitTypeDef* PWMLED_InitStructure)
{
	uint16_t pwmledcon_reg = 0,pwmledperiod_reg = 0,pwmleddut_reg = 0,pwmledwtm_reg = 0,pwmleddatadut_reg = 0;
	
	
	PWMLEDx->PWMCON = 0;
	
	pwmledcon_reg |= (PWMLED_InitStructure->PWMLED_Prescaler<<8) & CKD_SET_Mask;
	
	pwmledcon_reg |= PWMLED_InitStructure->PWMLEDDATA_Polarity & POL_SET_Mask;
	
	pwmledcon_reg |= PWMLED_InitStructure->PWMLED_SendNUM & MOD_SET_Mask;
	
	pwmledcon_reg |= PWMLED_InitStructure->PWMLED_Polarity & TOG_SET_Mask;
	
	PWMLEDx->PWMCON = pwmledcon_reg;
	
	PWMLEDx->PWMDIV = 0;	
	pwmledperiod_reg = PWMLED_InitStructure->PWMLED_Period & DIV_SET_Mask;	
	PWMLEDx->PWMDIV = pwmledperiod_reg;	
	
	
	PWMLEDx->PWMDUT = 0;
	pwmleddut_reg = PWMLED_InitStructure->PWMLED_Pulse & DUT_SET_Mask;	
	PWMLEDx->PWMDUT = pwmleddut_reg;
	
	PWMLEDx->LEDWTM = 0;	
	pwmledwtm_reg = PWMLED_InitStructure->PWMLEDSTOP_Count & WTM_SET_Mask;	
	PWMLEDx->LEDWTM = pwmledwtm_reg;
	
	PWMLEDx->LEDDUT = 0;	
	pwmleddatadut_reg = ((PWMLED_InitStructure->PWMLED_Period & DIV_SET_Mask) - (PWMLED_InitStructure->PWMLED_Pulse & DUT_SET_Mask)) & DATADUT_SET_Mask;	
	PWMLEDx->LEDDUT = pwmleddatadut_reg;
}


/**
  * @brief  Fills each PWMLED_InitStructure member with its default value.
  * @param  USART_InitStruct: pointer to a PWMLED_InitTypeDef structure
  *         which will be initialized.
  * @retval None
  */
void PWMLED_StructInit(PWMLED_InitTypeDef* PWMLED_InitStructure)
{

	PWMLED_InitStructure->PWMLED_Period = 0xFFFF;
	PWMLED_InitStructure->PWMLED_Prescaler = PWMLED_PSC_DIV0;
	PWMLED_InitStructure->PWMLED_Pulse = 0;
	PWMLED_InitStructure->PWMLED_Polarity = PWMLED_Polarity_Low;
	PWMLED_InitStructure->PWMLEDDATA_Polarity = PWMLEDDATA_Polarity_High;
	PWMLED_InitStructure->PWMLED_SendNUM = PWMLED_SendNUM_0;
	PWMLED_InitStructure->PWMLEDSTOP_Count = 0;
	
}

/**
  * @brief  Enables or disables the specified PWMLED peripheral.
  * @param  PWMLEDx: Select the PWMLED peripheral. 
  * @param  NewState: new state of the PWMLEDx peripheral.
  *         This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void PWMLED_Cmd(PWMLED_TypeDef* PWMLEDx, FunctionalState NewState)
{
	uint16_t pwmledcon_reg = 0;
	
	pwmledcon_reg = PWMLEDx->PWMCON;
	
	if(NewState != DISABLE)
	{
		pwmledcon_reg |= EN_SET_Mask;
	}
	else
	{
		pwmledcon_reg &= ~EN_SET_Mask;
	}
	
	PWMLEDx->PWMCON = pwmledcon_reg;
}


/**
  * @brief  Transmits single data through the PWMLED peripheral.
  * @param  PWMLEDx: Select the PWMLED peripheral. 
  * @param  Data: the data to transmit.
  * @retval None
  */
void PWMLED_SendData(PWMLED_TypeDef* PWMLEDx,uint8_t Data)
{
	uint16_t pwmleddat_reg = 0;
	uint16_t tmp_data = Data;
	
	pwmleddat_reg |= (tmp_data & DATA_SET_Mask);
	
	PWMLEDx->LEDDAT = pwmleddat_reg;
}

/**
  * @brief  Enables or disables the specified PWMLED interrupts.
  * @param  PWMLEDx: Select the PWMLED peripheral. 
  * @param  PWMLED_IT: specifies the PWMLED interrupt sources to be enabled or disabled.
  *   This parameter can be one of the following values:
  *     @arg PWMLED_IT_Updata:  PWM  Updata interrupt
  * @param  NewState: new state of the specified USARTx interrupts.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void PWMLED_ITConfig(PWMLED_TypeDef* PWMLEDx, uint16_t PWMLED_IT, FunctionalState NewState)
{
		uint16_t pwmledcon_reg = 0;
		pwmledcon_reg = PWMLEDx->PWMCON;
		
		if(NewState != DISABLE)
		{
				if(PWMLED_IT == PWMLED_IT_EN)
				{
					pwmledcon_reg |= PWMLED_IT_EN;
				}
		}
		else
		{
				if(PWMLED_IT == PWMLED_IT_EN)
				{
					pwmledcon_reg &= ~PWMLED_IT_EN;
				}		
		}
		PWMLEDx->PWMCON = pwmledcon_reg;
}

/**
  * @brief  Sets the PWMLED clock prescaler.
  * @param  PWMLEDx: Select the PWMLEDx peripheral. 
  * @param  PWMLED_Prescaler: specifies the prescaler clock. 
  * @retval None
  */
void PWMLED_SetPrescaler(PWMLED_TypeDef* PWMLEDx, uint8_t PWMLED_Prescaler)
{
		uint16_t pwmledcon_reg = 0;
		pwmledcon_reg = PWMLEDx->PWMCON;
		pwmledcon_reg |= (PWMLED_Prescaler<<8) & CKD_SET_Mask;
		PWMLEDx->PWMCON = pwmledcon_reg;
}

/**
  * @brief  Checks whether the specified PWMLED flag is set or not.
  * @param  PWMLEDx: Select the PWMLED peripheral. 
  * @param  PWMLED_FLAG: specifies the flag to check.
  *   This parameter can be one of the following values:
  *     @arg PWMLED_FLAG_BUSY:  PWMLED Busy flag 
  *     @arg PWMLED_FLAG_BF:  PWMLED Buff Full flag
  * @retval None.
  */
FlagStatus PWMLED_GetFlagStatus(PWMLED_TypeDef* PWMLEDx, uint16_t PWMLED_FLAG)
{
		FlagStatus ret = RESET;
		
		if(PWMLEDx->LEDDAT&PWMLED_FLAG)
		{
			ret = SET;
		}
		return ret;
}
/**
  * @brief  Clears the PWMLEDx's pending flags.
  * @param  PWMLEDx: Select the PWMLED peripheral. 
  * @param  PWMLED_FLAG: specifies the flag to check.
  *   This parameter can be one of the following values:
  *     @arg PWMLED_FLAG_BUSY:  PWMLED Busy flag 
  *     @arg PWMLED_FLAG_BF:  PWMLED Buff Full flag
  * @retval None.
  */
void PWMLED_ClearFlag(PWMLED_TypeDef* PWMLEDx, uint16_t PWMLED_FLAG)
{
		uint16_t pwmleddat_reg = 0;
	
		pwmleddat_reg = PWMLEDx->LEDDAT;
		pwmleddat_reg &= ~PWMLED_FLAG;
	
		PWMLEDx->LEDDAT = pwmleddat_reg;
}
/**
  * @brief  Checks whether the specified PWMLED interrupt has occurred or not.
  * @param  PWMLEDx: Select the PWMLED peripheral. 
  * @param  PWMLED_IT: specifies the PWMLED interrupt source to check.
  *   This parameter can be one of the following values:
  *     @arg PWMLED_IT_Updata: PWMLED Updata  interrupt 
  * @retval The new state of USART_IT (SET or RESET).
  */
ITStatus PWMLED_GetITStatus(PWMLED_TypeDef* PWMLEDx, uint16_t PWMLED_IT)
{
		ITStatus ret = RESET;
		uint16_t pwmledcon_reg = 0;
	
		pwmledcon_reg = PWMLEDx->PWMCON;
		if(pwmledcon_reg&PWMLED_IT_EN)
		{
			if(pwmledcon_reg&PWMLED_IT_Updata)
			{
				ret = SET;
			}
		}
		
		return ret;
}
/**
  * @brief  Clears the PWMLEDx's interrupt pending bits.
  * @param  PWMLEDx: Select the PWMLED peripheral. 
  * @param  PWMLED_IT: specifies the PWMLED interrupt source to check.
  *   This parameter can be one of the following values:
  *     @arg PWMLED_IT_Updata: PWMLED Updata  interrupt 
  * @retval None.
  */
void PWMLED_ClearITPendingBit(PWMLED_TypeDef* PWMLEDx, uint16_t PWMLED_IT)
{
		uint16_t pwmledcon_reg = 0;
	
		pwmledcon_reg = PWMLEDx->PWMCON;
		if(pwmledcon_reg&PWMLED_IT_EN)
		{
			if(pwmledcon_reg&PWMLED_IT_Updata)
			{
				pwmledcon_reg |= PWMLED_IT_Updata;
				PWMLEDx->PWMCON = pwmledcon_reg;
			}
		}	
}
/**
  * @brief  Set the PWMLEDx's LED data '1' pulse.
  * @param  PWMLEDx: Select the PWMLED peripheral. 
  * @param  One_Duty: PWMLEDx's LED data '1' pulse.
  * @retval None.
  */
void PWMLED_SetHighDuty(PWMLED_TypeDef* PWMLEDx,uint16_t One_Duty)
{
		uint16_t pwmleddut_reg = 0,pwmledperiod_reg = 0,pwmdut_reg = 0;
	
		pwmdut_reg = PWMLEDx->PWMDUT & DUT_SET_Mask;
		pwmledperiod_reg = PWMLEDx->PWMDIV & DIV_SET_Mask;
	
		pwmleddut_reg = One_Duty & DATADUT_SET_Mask;
	
		pwmdut_reg = pwmledperiod_reg - pwmleddut_reg;
	
		pwmdut_reg = pwmdut_reg; //for no warning
	
		PWMLEDx->PWMDUT = pwmleddut_reg;
		PWMLEDx->LEDDUT = pwmleddut_reg;
}

/**
  * @brief  Set the PWMLEDx's LED data Polarity.
  * @param  PWMLEDx: Select the PWMLED peripheral. 
  * @param  Polarity: PWMLEDx's LED Polarity.
	*					This parameter can be one of the following values:
	*	@param	PWMLEDDATA_Polarity_High: Data backlash
	*	@param	PWMLEDDATA_Polarity_Low:  Data don`t backlash
  * @retval None.
  */
void PWMLED_SetDataPolarity(PWMLED_TypeDef* PWMLEDx,uint8_t PWMLED_Polarity)
{
		uint16_t pwmledcon_reg = 0;
		
		pwmledcon_reg = PWMLEDx->PWMCON;
		if(PWMLED_Polarity == PWMLEDDATA_Polarity_High)
		{
			pwmledcon_reg |= PWMLEDDATA_Polarity_High;
		}
		else
		{
			pwmledcon_reg &= ~PWMLEDDATA_Polarity_High;
		}
		
		PWMLEDx->PWMCON = pwmledcon_reg;
		
}




